home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / linuxcon.000 / linuxcon / linuxconf-1.6 / netconf / ipfw.c < prev    next >
C/C++ Source or Header  |  1996-06-12  |  6KB  |  275 lines

  1. #include <stdlib.h>
  2. #include <errno.h>
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <netdb.h>
  7. #include <linux/ip.h>
  8. #include <linux/tcp.h>
  9. #include <linux/udp.h>
  10. #include <linux/icmp.h>
  11. #include <linux/if.h>
  12. #include <linux/ip_fw.h>
  13. #include <unistd.h>
  14. #include <ctype.h>
  15. #include <string.h>
  16. #include "netconf.h"
  17. #include "../misc/misc.h"
  18.  
  19. #ifndef IP_FW_POLICY_IN
  20.     /* These are just here so it compiles */
  21.     #define IP_FW_POLICY_IN        0
  22.     #define IP_FW_FLUSH_IN        1
  23.     #define IP_FW_APPEND_IN        2
  24.     #define IP_FW_POLICY_OUT    3
  25.     #define IP_FW_FLUSH_OUT        4
  26.  
  27.     #define FIREWALL_NONE
  28. #endif
  29.  
  30.  
  31.  
  32.  
  33.  
  34. static int sockfd = -1;
  35.  
  36. int ipfw_append (
  37.     int doit,
  38.     SSTRING *collect,
  39.     int command,
  40.     struct ip_fw &b)
  41. {
  42.     int ret = 0;
  43.     if (collect != NULL){
  44.         /* #Specification: firewall / formatting output
  45.             While programming the firewall, we compose in a string
  46.             the same format as will be created by the kernel in one
  47.             of the file /proc/net/ip_input or /proc/net/ip_forward.
  48.  
  49.             So it become possible to compare this with the current
  50.             content of those file and tell if something as to be done.
  51.         */
  52.         #ifndef FIREWALL_NONE
  53.             char buffer[300];
  54.             int len=sprintf(buffer,"%08lX/%08lX->%08lX/%08lX %.16s %08lX %X "
  55.                 ,ntohl(b.fw_src.s_addr),ntohl(b.fw_smsk.s_addr)
  56.                 ,ntohl(b.fw_dst.s_addr),ntohl(b.fw_dmsk.s_addr)
  57.                 ,(b.fw_vianame)[0] ? b.fw_vianame : "-"
  58.                 ,ntohl(b.fw_via.s_addr),b.fw_flg);
  59.             len+=sprintf(buffer+len,"%u %u %-9lu %-9lu"
  60.                 ,b.fw_nsp,b.fw_ndp, b.fw_pcnt,b.fw_bcnt);
  61.             for (int p = 0; p < IP_FW_MAX_PORTS; p++)
  62.                 len+=sprintf(buffer+len, " %u", b.fw_pts[p]);
  63.             sprintf(buffer+len, " A%02X X%02X\n", b.fw_tosand, b.fw_tosxor);
  64.  
  65.             collect->append (buffer);
  66.         #endif
  67.     }
  68.     if (doit){
  69.         ret = setsockopt (sockfd, IPPROTO_IP, command
  70.             ,&b,sizeof(struct ip_fw));
  71.         if (ret != 0){
  72.             xconf_error ("error append firewall %d(%s)",errno,strerror(errno));
  73.         }
  74.     }
  75.     return ret;
  76. }
  77.  
  78. int ipfw_flush (
  79.     int doit,
  80.     SSTRING *,
  81.     int command)
  82. {
  83.     int ret = 0;
  84.     if (doit){
  85.         int data = 0;
  86.         ret = setsockopt (sockfd, IPPROTO_IP, command,&data,sizeof(data));
  87.         if (ret != 0){
  88.             xconf_error ("error flush firewall %d(%s)",errno,strerror(errno));
  89.         }
  90.     }
  91.     return ret;
  92. }
  93.   
  94. int ipfw_policy (
  95.     int doit,
  96.     SSTRING *collect,
  97.     int command,
  98.     int policy)
  99. {
  100.     int ret = 0;
  101.     if (collect != NULL){
  102.         char *ctl = NULL;
  103.         switch (command){
  104.         case IP_FW_POLICY_IN:
  105.             ctl = "IP firewall input rules, default %d\n";
  106.             break;
  107.         case IP_FW_POLICY_OUT:
  108.             ctl = "IP firewall output rules, default %d\n";
  109.             break;
  110.         case IP_FW_POLICY_FWD:
  111.             ctl = "IP firewall forward rules, default %d\n";
  112.             break;
  113.         }
  114.         char buf[100];
  115.         sprintf(buf,ctl,policy);
  116.         collect->append (buf);
  117.     }
  118.     if (doit){
  119.         ret = setsockopt (sockfd, IPPROTO_IP, command,&policy,sizeof(policy));
  120.     }
  121.     return ret;
  122. }
  123.   
  124. /*
  125.     Initialise the sockfd needed to program the rules
  126.     Return -1 if any error.
  127. */
  128. int ipfw_open ()
  129. {
  130.     sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  131.     return sockfd;
  132. }
  133.  
  134.  
  135. void ipfw_close()
  136. {
  137.     close (sockfd);
  138.     sockfd = -1;
  139. }
  140.  
  141. #ifndef FIREWALL_NONE
  142. /*
  143.     Translate and validate an ASCII IP addr.
  144. */
  145. static int ipfw_a2ip (const char *adr, struct in_addr &ina)
  146. {
  147.     int num4[4];
  148.     int ret = device_aip24 (adr,num4);
  149.     if (ret != -1){
  150.         unsigned long ipa = (num4[0] <<24) | (num4[1] << 16)
  151.             | (num4[2] << 8) | num4[3];
  152.         ina.s_addr = htonl (ipa);
  153.     }
  154.     return ret;
  155. }
  156.  
  157. static int ipfw_setrange (
  158.     const char *range,
  159.     struct ip_fw &bf,
  160.     int flag,
  161.     int noport,
  162.     unsigned short &nb)
  163. {
  164.     const char *s = str_skip (range);
  165.     if (s[0] != '\0'){
  166.         bf.fw_flg |= flag;
  167.         bf.fw_pts[noport++] = atoi(s);
  168.         s = str_skipdig (s);
  169.         s = str_skip (s);
  170.         if (*s == ':') s++;
  171.         s = str_skip (s);
  172.         bf.fw_pts[noport++] = atoi(s);
  173.         nb = 2;
  174.     }
  175.     return noport;
  176. }
  177.  
  178. static int ipfw_setports (
  179.     const char *ports,
  180.     struct ip_fw &bf,
  181.     unsigned short &nb,
  182.     int noport,
  183.     const char *proto)
  184. {
  185.     while (1){
  186.         ports = str_skip (ports);
  187.         if (ports[0] == '\0'){
  188.             break;
  189.         }else{
  190.             char word[200];
  191.             ports = str_copyword(word,ports);
  192.             int port = atoi(word);
  193.             struct servent *serv = getservbyname (word,proto);
  194.             if (serv != NULL) port = ntohs(serv->s_port);
  195.             bf.fw_pts[noport++] = port;
  196.             nb++;
  197.         }
  198.     }
  199.     return noport;
  200. }
  201.     
  202. /*
  203.     Return -1 if anything is invalid
  204. */
  205. int ipfw_baseinit (
  206.     const char *iface,
  207.     const char *protocol,
  208.     const char *ip_src,
  209.     const char *msk_src,
  210.     const char *sport_range,
  211.     const char *sports,
  212.     const char *ip_dst,
  213.     const char *msk_dst,
  214.     const char *dport_range,
  215.     const char *dports,
  216.     struct ip_fw &bf)
  217. {
  218.     memset (&bf,0,sizeof(bf));
  219.     int ret = ipfw_a2ip (ip_src,bf.fw_src);
  220.     ret |= ipfw_a2ip (msk_src,bf.fw_smsk);
  221.     bf.fw_src.s_addr &= bf.fw_smsk.s_addr;
  222.     ret |= ipfw_a2ip (ip_dst,bf.fw_dst);
  223.     ret |= ipfw_a2ip (msk_dst,bf.fw_dmsk);
  224.     bf.fw_dst.s_addr &= bf.fw_dmsk.s_addr;
  225.     /* #Specification: firewall / iface / assumption
  226.         We assume that all network device do begin with a letter.
  227.         This way we differentiate IP number for interface from name
  228.     */
  229.     if (isalpha(iface[0])){
  230.         strcpy (bf.fw_vianame,iface);
  231.     }else{
  232.         ret |= ipfw_a2ip (iface,bf.fw_via);
  233.     }
  234.     if (stricmp(protocol,"all")==0){
  235.         bf.fw_flg = IP_FW_F_ALL;
  236.     }else if (stricmp(protocol,"tcp")==0){
  237.         bf.fw_flg = IP_FW_F_TCP;
  238.     }else if (stricmp(protocol,"udp")==0){
  239.         bf.fw_flg = IP_FW_F_UDP;
  240.     }else if (stricmp(protocol,"icmp")==0){
  241.         bf.fw_flg = IP_FW_F_ICMP;
  242.     }else{
  243.         ret = -1;
  244.     }
  245.     int noport = ipfw_setrange (sport_range,bf,IP_FW_F_SRNG,0,bf.fw_nsp);
  246.     noport = ipfw_setports (sports,bf,bf.fw_nsp,noport,protocol);
  247.     noport = ipfw_setrange (dport_range,bf,IP_FW_F_DRNG,noport,bf.fw_ndp);
  248.     ipfw_setports (dports,bf,bf.fw_ndp,noport,protocol);
  249.  
  250.     bf.fw_tosand = 0xFF;
  251.     bf.fw_tosxor = 0x00;
  252.     bf.fw_flg |= IP_FW_F_ACCEPT;
  253.     return ret;
  254. }
  255.  
  256. #else
  257.  
  258. int ipfw_baseinit (
  259.     const char *,
  260.     const char *,
  261.     const char *,
  262.     const char *,
  263.     const char *,
  264.     const char *,
  265.     const char *,
  266.     const char *,
  267.     const char *,
  268.     const char *,
  269.     struct ip_fw &)
  270. {
  271.     return -1;
  272. }
  273.  
  274. #endif
  275.